from __future__ import annotations
from abc import ABC, abstractmethod
from typing import List


class Subject(ABC):
    def __init__(self):
        self._observers: List[Observer] = []
        self._changed: bool = False

    def register_observer(self, o: Observer):
        if o not in self._observers:
            self._observers.append(o)

    def remove_observer(self, o: Observer):
        if o in self._observers:
            self._observers.remove(o)

    def notify_observers(self):
        if self._changed:
            for i in self._observers:
                i.update(self)
        self._changed = False

    def _set_change(self):
        self._changed = True


class Observer(ABC):
    @abstractmethod
    def update(self, subject: Subject):
        ...


class SimpleSubject(Subject):
    def __init__(self):
        super().__init__()
        self._value: int = 0

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = value
        self._set_change()
        self.notify_observers()


class SimpleObserver(Observer):
    def __init__(self, subject: Subject):
        if isinstance(subject, SimpleSubject):
            subject.register_observer(self)
            self._value = subject.value

    def update(self, subject: Subject):
        if isinstance(subject, SimpleSubject):
            self._value = subject.value
            self.display()

    def display(self):
        print(f"Value: {self._value}")


if __name__ == '__main__':
    simple_subject = SimpleSubject()
    simple_observer = SimpleObserver(simple_subject)
    simple_subject.value = 80
    simple_subject.remove_observer(simple_observer)
